package com.llg.util.formula;

import com.llg.pojo.FormulaPO;
import com.llg.repository.FormulaPORepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * 公式管理器
 */
@Component
@Slf4j
public class FormulaManager {

    private final FormulaPORepository formulaRepository;

    // 存放已经实例化的公式
    private final Map<Integer, Formula> map = new HashMap<>();

    @Autowired
    public FormulaManager(FormulaPORepository formulaRepository) {
        this.formulaRepository = formulaRepository;
    }

    /**
     * 根据id获取一个公式
     * @param id id
     * @return 公式对象
     */
    @Nullable
    public Formula getFormula(int id) {
        if (map.containsKey(id)) {
            return map.get(id);
        }
        return putFormula(id);
    }

    @Nullable
    public Formula putFormula(int id) {
        Optional<FormulaPO> optional = formulaRepository.findById(id);
        if (optional.isPresent()) {
            try {
                FormulaPO formulaPo = optional.get();
                ClassLoader classLoader = this.getClass().getClassLoader();
                Class<?> loadClass = classLoader.loadClass(formulaPo.getClassName());
                if (loadClass == null) {
                    return null;
                }
                Method create = loadClass.getDeclaredMethod("create", String.class);
                create.setAccessible(true);
                Formula invoke = (Formula) create.invoke(null, formulaPo.getFormula());
                map.put(formulaPo.getId(), invoke);
                return invoke;
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }

        }
        return null;
    }
}
